using System;

namespace Infrastructure
{
    /// <summary>
    /// Url编码和解码的类
    /// </summary>
    public static class Url
    {
        /// <summary>
        /// 对文本进行Url编码('+'替换为'-'并且'/'替换为'_')
        /// </summary>
        /// <param name="text">文本</param>
        /// <returns>Url编码后的文本</returns>
        public static string Encode(string text)
        {
            // 进行Url编码('+'替换为'-'并且'/'替换为'_')
            return text.Replace('+', '-').Replace('/', '_');
        }

        /// <summary>
        /// 字节数组转换为Base64字符串并进行Url编码。
        /// 进行Url编码的Base64字符串移除了末尾的'='。
        /// </summary>
        /// <param name="bytes">需要编码的字节数组</param>
        /// <returns>编码结果</returns>
        public static string EncodeBase64(byte[] bytes)
        {
            // 字节数组为空
            if (bytes == null || bytes.Length == 0)
                return string.Empty;

            // 字节数组转换为Base64字符串
            string base64String = Convert.ToBase64String(bytes);

            // 移除末尾的'='
            base64String = base64String.Split('=')[0];
            
            // Url编码
            return Encode(base64String);
        }

        /// <summary>
        /// 对文本进行Url解码('-'替换为'+'并且'_'替换为'/')
        /// </summary>
        /// <param name="text">Url编码的文本</param>
        /// <returns>Url解码后的文本</returns>
        public static string Decode(string text)
        {
            // 还原文本
            // '-'替换为'+'并且'_'替换为'/'
            return text.Replace('-', '+').Replace('_', '/');
        }
        
        /// <summary>
        /// 字符串进行Url解码并转换为Base64字节数组。
        /// 字符串将自动补齐末尾的'='。
        /// </summary>
        /// <param name="base64UrlString">需要解码的字符串</param>
        /// <returns>解码结果</returns>
        public static byte[] DecodeBase64(string base64UrlString)
        {
            // 字符串为空
            if (string.IsNullOrEmpty(base64UrlString))
                return null;

            // Url解码
            string base64String = base64UrlString;
            base64String = Decode(base64String);

            // 补齐末尾的'='
            switch (base64String.Length % 4)
            {
                case 0: break;                       // 无需补齐
                case 2: base64String += "=="; break; // 补齐2个'='
                case 3: base64String += "="; break;  // 补齐1个'='
                default: return null;                // 不正确的字符串，返回
            }

            // Base64字符串转换为字节数组
            return Convert.FromBase64String(base64String);
        }

    }
}
